home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ian & Stuart's Australian Mac 1993 September
/
September 93.iso
/
Archives
/
Utilities
/
System
/
FKey
/
FKeys
/
tsv4.0.2
/
src
/
Quik FKEY Installer.c
next >
Wrap
C/C++ Source or Header
|
1992-05-31
|
15KB
|
733 lines
/* Quik FKEY Installer.c ©1992 by Mike Gleason Jr. */
#ifndef nil
# define nil ((void *) 0)
#endif
#ifndef __PACKAGES__
# include <Packages.h>
#endif
#define appleID 400
#define fileID 401
#define tryItItem 1
#define systemItem 3
#define suitcaseItem 4
#define removeSystemItem 6
#define removeSuitItem 7
#define quitItem 9
#define editID 402
#define SystemResFile 0
#define rAboutALRT 129
#define rStrList 128
#define rAboutFkeyDLOG 130
#define rFkeyAboutTxt 128
#define infoW 492
#define infoH 20
#define infoM 10
#define kExistingRsrc 99
WindowPtr gMsgWindow;
Boolean gHasWaitNextEvent;
SysEnvRec gMac;
short gID;
Str255 gName;
Handle gFkey, gFkeyAboutTxt;
long gFkeyAboutTxtSize;
CursHandle gWatch;
void main(void);
void InitMacintosh(void);
void SetUpMenus(void);
short HandleEvent(void);
void HandleMouseDown(EventRecord *theEvent);
void HandleMenu (long mSelect);
void Message(unsigned char *str, long delay, Boolean killWhenDone);
unsigned char *pStrcat(unsigned char *s, register unsigned char *t);
unsigned char *pStrcpy(register unsigned char *s, register unsigned char *t);
OSErr SFGet(Str255 name, short *vref, long *dirid);
Boolean SFPut(Str255 name);
void Install(Boolean useSystemFile);
OSErr SFSystemDirectory(void);
OSErr SFDirID(short wd, short *volume, long *folder);
short CopyResource(short src, short dst, ResType type, short srcID, short dstID);
void About(void);
void Remove(Boolean useSystemFile);
short OpenDestFile(void);
pascal Boolean ResourceFilesOnly(ParmBlkPtr p);
void CloseMessage(void);
short KillOld(short dstResFile);
void TryIt(void);
void AboutFKEY(void);
pascal void AboutTxtUserItem(DialogPtr d, short itemNum);
pascal void AboutTxtUserItem(DialogPtr d, short itemNum)
{
Handle itemH;
short itemType, a, b;
Rect itemR;
SetPort(d);
a = d->txFont; b = d->txSize;
if (RealFont(times, 12))
TextFont(times);
else {
TextFont(geneva);
TextSize(9);
}
GetDItem(d, itemNum, &itemType, &itemH, &itemR);
HLock(gFkeyAboutTxt);
TextBox(*gFkeyAboutTxt, gFkeyAboutTxtSize, &itemR, teJustLeft);
HUnlock(gFkeyAboutTxt);
TextFont(a); TextSize(b);
} /* AboutTxtUserItem */
void AboutFKEY(void)
{
DialogPtr dptr;
Handle itemH;
short itemType, itemHit;
Rect itemR;
if (dptr = GetNewDialog(rAboutFkeyDLOG, nil, (WindowPtr) -1)) {
SetPort(dptr);
GetDItem(dptr, 2, &itemType, &itemH, &itemR);
SetDItem(dptr, 2, itemType, (Handle) AboutTxtUserItem, &itemR);
ShowWindow(dptr);
SelectWindow(dptr);
/* Make a default button's thick outline: */
GetDItem(dptr, 1, &itemType, &itemH, &itemR);
InsetRect(&itemR, -4, -4);
PenSize(3, 3);
FrameRoundRect(&itemR, 16, 16);
PenNormal();
InitCursor();
do {
ModalDialog(nil, &itemHit);
} while (itemHit != 1);
DisposDialog(dptr);
}
} /* AboutFKEY */
void main(void)
{
OSType type;
InitMacintosh();
gMsgWindow = nil;
if (gFkeyAboutTxt = Get1Resource('TEXT', rFkeyAboutTxt))
gFkeyAboutTxtSize = SizeResource(gFkeyAboutTxt);
gFkey = Get1IndResource('FKEY', 1);
if (!gFkey)
ExitToShell();
GetResInfo(gFkey, &gID, &type, gName);
if (!*gName)
pStrcpy(gName, "\pUntitled");
gWatch = (CursHandle) RGetResource('CURS', watchCursor);
SetUpMenus();
About();
HandleEvent();
} // main
void InitMacintosh(void)
{
MaxApplZone();
InitGraf(&thePort);
InitFonts();
FlushEvents(everyEvent, 0);
InitWindows();
InitMenus();
TEInit();
InitDialogs(0L);
InitCursor();
SysEnvirons(1, &gMac);
#define WNETrapNum 0x60 /* Trap number of WaitNextEvent() */
#define UnImplTrapNum 0x9F /* Trap number "unimplemented trap" */
gHasWaitNextEvent = NGetTrapAddress(WNETrapNum, ToolTrap) !=
NGetTrapAddress(UnImplTrapNum, ToolTrap);
} // InitMacintosh
void SetUpMenus(void)
{
MenuHandle mh;
unsigned char str[256];
InsertMenu(mh = NewMenu(appleID, "\p\024"), 0);
pStrcpy(str, "\pAbout Quick FKEY Installer…;");
if (gFkeyAboutTxt) {
pStrcat(str, "\pAbout ");
pStrcat(str, gName);
pStrcat(str, "\p…");
}
AppendMenu(mh, str);
AddResMenu(mh, 'DRVR');
InsertMenu(mh = NewMenu(fileID, "\pFile"), 0);
pStrcpy(str, "\pTry ");
pStrcat(str, gName);
pStrcat(str, "\p/J;-)");
AppendMenu(mh, str);
AppendMenu(mh, "\pInstall in System File;Install in a “Suitcase” File;(-;Remove from System File;Remove from “Suitcase” File;(-;Quit/Q");
DrawMenuBar();
} // SetUpMenus
short HandleEvent(void)
{
short ok, ch;
EventRecord theEvent;
while (1) {
InitCursor();
if ( gHasWaitNextEvent ) {
ok = WaitNextEvent(everyEvent, &theEvent, 90L, nil);
} else {
SystemTask();
ok = GetNextEvent(everyEvent, &theEvent);
}
if (ok)
switch (theEvent.what) {
case mouseDown:
HandleMouseDown(&theEvent);
break;
case keyDown:
case autoKey:
ch = (theEvent.message & charCodeMask);
if ((theEvent.modifiers & cmdKey) != 0)
HandleMenu(MenuKey(ch));
break;
}
}
} /* HandleEvent */
void HandleMouseDown(EventRecord *theEvent)
{
WindowPtr theWindow;
short windowCode = FindWindow (theEvent->where, &theWindow);
switch (windowCode) {
case inSysWindow:
SystemClick (theEvent, theWindow);
break;
case inMenuBar:
HandleMenu(MenuSelect(theEvent->where));
}
} /* HandleMouseDown */
void HandleMenu (long mSelect)
{
short menuID = HiWord(mSelect);
short menuItem = LoWord(mSelect);
unsigned char name[256];
GrafPtr savePort;
WindowPeek frontWindow;
HiliteMenu(0);
switch (menuID) {
case appleID:
GetPort(&savePort);
GetItem(GetMHandle(appleID), menuItem, name);
if (menuItem > 2)
OpenDeskAcc(name);
else {
if (menuItem == 1)
About();
else
AboutFKEY();
}
SetPort(savePort);
break;
case fileID:
switch (menuItem) {
case tryItItem:
TryIt();
break;
case systemItem:
Install(true);
break;
case suitcaseItem:
Install(false);
break;
case removeSystemItem:
Remove(true);
break;
case removeSuitItem:
Remove(false);
break;
case quitItem:
ExitToShell();
break;
}
break;
} /* end of menu numbers */
} // HandleMenu
void TryIt(void)
{
typedef void (**ProcHandle)(void);
SignedByte state;
ProcHandle p;
Str255 s = "\pRunning “";
ResLoad = true;
p = (ProcHandle) Get1IndResource('FKEY', 1);
if (p) {
if (!*p)
Message("\pCouldn't load the FKEY!", 180L, true);
else {
state = HGetState((Handle) p);
HLock((Handle) p);
HNoPurge((Handle) p);
pStrcat(s, gName);
pStrcat(s, "\p…”");
Message(s, 45L, false);
(**p)();
HSetState((Handle) p, state);
CloseMessage();
}
} else
Message("\pCouldn't find the FKEY in this installer!", 180L, true);
} // TryIt
short KillOld(short dstResFile)
{
short i, j, del, id, old;
OSType type;
Handle h;
Str255 killName, str;
old = CurResFile();
GetIndString(killName, rStrList, 1);
UseResFile(dstResFile);
// First, delete any duplicates of this FKEY.
if ((h = Get1NamedResource('FKEY', gName))) {
RmveResource(h);
del++;
}
// Next delete all FKEYs whose name begins with 'killName,'
// so if we have killName="MyFkey", we can delete "MyFkey 1.2", etc.
j = Count1Resources('FKEY');
for (i=1, del=0; i<=j; i++) {
h = Get1IndResource('FKEY', i);
GetResInfo(h, &id, &type, str);
if (ResErr || *str < *killName)
continue;
else if (*str > *killName)
*str = *killName;
if (IUEqualString(str, killName) == 0) {
RmveResource(h);
del++;
}
}
if (del > 0)
UpdateResFile(dstResFile);
UseResFile(old);
return del;
} // KillOld
short OpenDestFile(void)
{
Str255 destName;
short vref, a;
long dirid;
(void) SFSystemDirectory();
if (SFGet(destName, &vref, &dirid))
return (-1);
a = HOpenResFile(vref, dirid, destName, fsRdWrShPerm);
if (ResErr)
a = -1;
return a;
} // OpenDestFile
void Remove(Boolean useSystemFile)
{
short destResFile, del;
if (useSystemFile) {
SetCursor(*gWatch);
del = KillOld(SystemResFile);
} else {
Message("\pSelect the file you want the FKEY removed from:", 0L, false);
destResFile = OpenDestFile();
if (destResFile != -1) {
SetCursor(*gWatch);
del = KillOld(destResFile);
CloseResFile(destResFile);
} else
goto x;
}
if (del)
Message("\pRemoved successfully.", 120L, true);
else
Message("\pNo FKEYs removed from this file.", 120L, true);
x: CloseMessage();
} // Remove
void Install(Boolean useSystemFile)
{
OSErr err;
short destResFile, myResFile, dstID, i, j;
unsigned char msg[256] = "\pInstalled “", tmp[8];
myResFile = CurResFile();
if (useSystemFile)
destResFile = SystemResFile;
else {
Message("\pSelect the file you want to install the FKEY in:", 0L, false);
destResFile = OpenDestFile();
if (destResFile == -1)
goto d2;
}
SetCursor(*gWatch);
// Delete obselete versions of the same FKEY first.
if (KillOld(destResFile))
Message("\pDeleted old version.", 60L, false);
// Try copying the resource verbatim.
dstID = gID;
err = CopyResource(myResFile, destResFile, 'FKEY', gID, dstID);
if (err < 0) {
Message("\pError occurred while copying the FKEY.", 180L, true);
goto done;
} else if (err == kExistingRsrc) {
// There already is an FKEY with id == gID.
// Try to install in another slot.
for (i=5; i<=10; i++) {
if (i == 10)
dstID = 0;
else
dstID = i;
err = CopyResource(myResFile, destResFile, 'FKEY', gID, dstID);
if (err && err != kExistingRsrc) {
Message("\pError occurred while copying the FKEY.", 180L, true);
goto done;
} else if (err == noErr) {
/* Hey! We found a slot for the fkey to fit. */
/* Message */
break; /* done, finally! */
} /* end if we installed in an alternate slot */
} /* end looping for empty slots */
} /* end if our preferred slot was filled */
if (err)
Message("\pSorry, there are already too many FKEYs in this file.", 180L, true);
else {
pStrcat(msg, gName);
pStrcat(msg, "\p” okay. Type command-shift-");
NumToString((long)dstID, tmp);
pStrcat(msg, tmp);
pStrcat(msg, "\p to run it. <Click>");
Message(msg, 120L, true);
} /* end notifying the user of a successful install */
done:
UseResFile(myResFile);
if (destResFile != SystemResFile)
CloseResFile(destResFile);
d2: CloseMessage();
} // Install
short CopyResource(short src, short dst, ResType type, short srcID, short dstID)
{
Handle RSRC = 0L, h;
short oldResFile;
OSErr err;
Str255 resname;
oldResFile = CurResFile();
UseResFile(dst);
RSRC = Get1Resource(type, dstID);
/* see if we have a resource with
the same id already present. */
err = ResError();
if (!err && RSRC) {
ReleaseResource(RSRC);
return (kExistingRsrc);
}
UseResFile(src);
RSRC = Get1Resource(type, srcID);
/* load the source rsrc */
if (err = ResError()) goto heave;
GetResInfo(RSRC, &srcID, &type, resname);
/* we need to do this to get the
resource's name, if any */
if (err = ResError()) goto heave;
UseResFile(dst);
h = RSRC;
HandToHand(&h);
if (!h) goto heave;
DetachResource(h); /* have to detach it to make a copy */
AddResource(h, type, dstID, resname);
/* now actually copy it */
if (err = ResError()) goto heave;
ChangedResource(h); /* mark it as changed */
if (err = ResError()) goto heave;
UpdateResFile(dst); /* write out the resource file */
err = ResError();
heave:
UseResFile(oldResFile);
return (err);
} /* CopyResource */
void CloseMessage(void)
{
if (gMsgWindow) {
DisposeWindow(gMsgWindow);
gMsgWindow = nil;
}
} // CloseMessage
void Message(unsigned char *str, long delay, Boolean killWhenDone)
{
Rect r;
short dy, quikMask = keyDownMask + autoKeyMask + mDownMask;
EventRecord E;
if (!gMsgWindow) {
SetRect(
&r,
infoM,
MBarHeight + infoM,
infoM + infoW,
MBarHeight + infoM + infoH
);
gMsgWindow = NewWindow(
0L, /* window's storage ptr, 0L usually */
&r, /* the window's rect */
"\pWindow Title", /* the window's title */
FALSE, /* is the window initially visible? */
dBoxProc, /* type of window */
(WindowPtr) -1L, /* front of which window, -1L = all */
0, /* has a go away box? */
0 /* window refnum */
);
if (gMsgWindow) {
ShowWindow(gMsgWindow);
SelectWindow(gMsgWindow);
} else
return;
}
SetPort(gMsgWindow);
EraseRect(&gMsgWindow->portRect);
TextFont(times);
TextSize(12);
MoveTo((infoW - StringWidth(str)) / 2, 14);
DrawString(str);
/* delay until the mouse button is pressed, a key is
pressed, or 'TixToDelay' ticks has elapsed. This is a
better way than testing Button() all the time, 'cuz
it removes the event from the queue (otherwise when
you clicked it could select a background application */
if (delay > 0L) {
delay += Ticks;
while (Ticks < delay) {
if (GetNextEvent(quikMask, &E))
break;
SystemTask();
}
}
ValidRect(&gMsgWindow->portRect);
if (killWhenDone)
CloseMessage();
} // Message
unsigned char *pStrcat(unsigned char *s, register unsigned char *t)
{
register unsigned char *s2;
register short tLen;
s2 = s + *s;
*s += (tLen = *t);
for (++tLen; --tLen; s2[tLen] = t[tLen]);
return (s);
} /* pStrcat */
unsigned char *pStrcpy(register unsigned char *s, register unsigned char *t)
{
register short tLen;
for (tLen = *t + 1; tLen--; s[tLen] = t[tLen]);
return (s);
} /* pStrcpy */
pascal Boolean ResourceFilesOnly(ParmBlkPtr p)
{
return (!(p->fileParam.ioFlRLgLen > 0L));
/* return FALSE if you want a file to be shown in the list... */
} /* ResourceFilesOnly */
OSErr SFGet(Str255 name, short *vref, long *dirid)
{
SFReply reply;
SFTypeList typeList;
Point location = {0x40,0x40};
OSErr err;
location.v = MBarHeight + infoH + (3*infoM);
SFGetFile(
location, /* location */
"\pSpace for Rent", /* vestigial string */
ResourceFilesOnly, /* fileFilter */
-1, /* numtypes; -1 means all */
&typeList, /* array to types to show */
nil, /* dlgHook */
&reply /* record for returned values */
);
if (reply.good) {
pStrcpy(name, reply.fName);
if (err = SetVol(name, reply.vRefNum))
return (err);
*vref = -SFSaveDisk;
*dirid = CurDirStore;
return (noErr);
} else
return (1); /* nothing selected */
} /* SFGet */
OSErr SFSystemDirectory(void)
{
WDPBRec pb;
SysEnvRec theWorld;
Str255 name;
OSErr err;
if (err = SysEnvirons(1, &theWorld))
return (err);
pb.ioNamePtr = (StringPtr) name;
pb.ioCompletion = 0L;
pb.ioVRefNum = theWorld.sysVRefNum;
pb.ioWDIndex = 0;
pb.ioWDProcID = 0;
pb.ioWDVRefNum = 0;
if ((err = PBGetWDInfo(&pb,false)))
return (err);
CurDirStore = pb.ioWDDirID;
SFSaveDisk = -pb.ioWDVRefNum;
/* on the next SFGetFile (…) it will open in the System Folder. */
return (noErr);
} /* SFSystemDirectory */
void About(void)
{
ParamText(gName, nil, nil, nil);
(void) Alert(rAboutALRT, nil);
} /* About */
/* eof */